package com.demo.deal_service.controller;

import com.demo.deal_service.enums.ImageCutEnum;
import com.demo.deal_service.enums.ResultEnum;
import com.demo.deal_service.model.entity.Deal;
import com.demo.deal_service.model.entity.Order;
import com.demo.deal_service.model.result.ResultEntity;
import com.demo.deal_service.service.DealService;
import com.demo.deal_service.util.ImgUtil;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletResponseWrapper;
import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

import static java.util.stream.Collectors.toList;

@RestController("/")
public class DealController {

    private DealService dealService;

    public DealController(@Autowired DealService dealService) {
        this.dealService = dealService;
    }

    /**
     * 给controller自定义数据绑定规则
     *
     * @param request
     * @param binder
     * @throws Exception
     */
    @InitBinder
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                if (StringUtils.hasText(text)) {
                    try {
                        Long timestamp = Long.parseLong(text);
                        setValue(new Date(timestamp));
                    } catch (NumberFormatException ex) {
                        throw new IllegalArgumentException("Could not parse date: " + ex.getMessage(), ex);
                    }
                }
            }
        });
    }

    /**
     * 分页获取列表
     *
     * @param pageNum
     * @return
     */
    @GetMapping("dealList") //FIXME 换成返回ResultEntity
    public ResponseEntity<PageInfo> getList(@RequestParam(required = false, defaultValue = "1") int pageNum) {
        PageInfo<Deal> pageInfo = dealService.getDealByPage(pageNum);
        pageInfo.getList()
                .forEach(deal -> {
                    deal.setImageUrl(ImgUtil.getRelativeGenPath(deal.getId(), ImageCutEnum.DEAL_SMALL_CUT));
                });
        return new ResponseEntity<>(pageInfo, HttpStatus.OK);
    }

    /**
     * 根据id获取详细信息
     *
     * @param id
     * @return
     */
    @GetMapping("deal/{id}") //FIXME 换成返回ResultEntity
    public ResponseEntity<Deal> getDeal(@PathVariable Long id) {
        Deal deal = dealService.getDealById(id);
        return new ResponseEntity<>(deal, HttpStatus.OK);
    }

    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @DeleteMapping("deal/{id}")
    public ResponseEntity<ResultEntity> deleteById(@PathVariable Long id) {
        ResultEntity resultEntity = dealService.deleteDeal(id);
        return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
    }

    /**
     * 添加
     *
     * @param deal
     * @param imgFile
     * @return
     */
    @PostMapping(value = "deal")
    public ResponseEntity<ResultEntity> addDeal(@Validated Deal deal, MultipartFile imgFile, BindingResult bindingResult) {
        ResultEntity resultEntity = null;

        if (bindingResult.hasErrors()) {
            List<String> strings = bindingResult
                    .getAllErrors()
                    .stream()
                    .map(ObjectError::toString)
                    .collect(toList());
            resultEntity = new ResultEntity<List>(ResultEnum.DEAL_ADD_FAIL_CHECK, strings, "数据校验失败");
            return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
        }

        resultEntity = dealService.addDeal(deal, imgFile);
        return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
    }

    @PostMapping(value = "deal/{id}")
    public ResponseEntity<ResultEntity> addDeal(@PathVariable Long id,  Deal deal, MultipartFile imgFile, BindingResult bindingResult) {
        ResultEntity resultEntity = null;

        if (bindingResult.hasErrors()) {
            List<String> strings = bindingResult
                    .getAllErrors()
                    .stream()
                    .map(ObjectError::toString)
                    .collect(toList());
            resultEntity = new ResultEntity<List>(ResultEnum.DEAL_ADD_FAIL_CHECK, strings, "数据校验失败");
            return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
        }

        deal.setId(id);
        resultEntity = dealService.editDeal(deal, imgFile);
        return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
    }

    @PostMapping(value = "deal/{id}/order")
    public ResponseEntity<ResultEntity> orderDeal(Order order,@PathVariable Long id) {
        ResultEntity resultEntity = null;
        resultEntity = dealService.genOrder(id, order);
        return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
    }

    /**
     * 拦截处理数据绑定异常
     *
     * @param bindingResult
     * @return
     */
    @ExceptionHandler(value = {org.springframework.validation.BindException.class})
    public ResponseEntity<?> handleBindException(BindingResult bindingResult) {
        ResultEntity resultEntity = null;
        if (bindingResult.hasErrors()) {
            List<FieldError> strings = bindingResult.getFieldErrors();
            resultEntity = new ResultEntity<List>(ResultEnum.DEAL_ADD_FAIL_CHECK, strings, "数据校验失败");
            return new ResponseEntity<>(resultEntity, resultEntity.getHttpStatus());
        }
        return new ResponseEntity<>("fail", HttpStatus.OK);
    }
}
